package main

import (
	"encoding/json"
	"fmt"
	io "io/ioutil"
	"math/rand"
	"os"
	"time"
)

type Rule struct {
	Name string `json:"name"`
	Args []int  `json:"args"`
}

type Hub struct {
	// Registered clients.
	clients map[*Client]bool

	// Inbound messages from the clients.
	broadcast chan []byte

	// Register requests from the clients.
	register chan *Client

	// Unregister requests from clients.
	unregister chan *Client
	rules      map[string]Rule
}

func (h *Hub) LoadConfig() {

	_, err := os.Lstat(path)
	if !os.IsNotExist(err) {
		fileLocker.Lock()
		data, err := io.ReadFile(path)
		fileLocker.Unlock()
		if err != err {
			return
		}
		dataJson := []byte(data)
		var rules map[string]Rule
		error := json.Unmarshal(dataJson, &rules)
		if error != nil {
			return
		}
		h.rules = make(map[string]Rule)
		for key := range rules {
			h.rules[key] = rules[key]
		}
	} else {
		f, err := os.Create(path)
		defer f.Close()
		if err != nil {
			fmt.Println(err.Error())
		}
	}

}

func newHub() *Hub {
	return &Hub{
		broadcast:  make(chan []byte),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		clients:    make(map[*Client]bool),
	}
}

func (h *Hub) run() {
	for {
		select {
		case client := <-h.register:
			h.clients[client] = true
		case client := <-h.unregister:
			if _, ok := h.clients[client]; ok {
				delete(h.clients, client)
				close(client.send)
			}
		case message := <-h.broadcast:
			var rules map[string]Rule
			//var msg map[string]interface{}
			json.Unmarshal(message, &rules)
			if h.rules == nil {
				h.rules = make(map[string]Rule)
			}

			for tag := range rules {
				h.rules[tag] = rules[tag]
			}

			if len(rules) > 0 {
				fmt.Println(rules)
				fileContent, err := json.Marshal(h.rules)
				if err = io.WriteFile(path, fileContent, 0666); err != nil {
					fmt.Println("Writefile Error =", err)
					return
				}
			}
		}
	}
}

func (h *Hub) SendData() {
	for {
		for tag := range h.rules {
			rule := h.rules[tag]
			var MsgByte []byte
			if rule.Name == "rand" {
				min := rule.Args[0]
				max := rule.Args[1]
				value := fmt.Sprintf("%d", rand.Intn(max-min)+min)
				var msgObj = make(map[string]string)
				msgObj["TagName"] = tag
				msgObj["TagValue"] = string(value)
				MsgByte, _ = json.Marshal(msgObj)

			}
			for client := range h.clients {
				select {
				case client.send <- MsgByte:
				default:
					close(client.send)
					delete(h.clients, client)
				}
			}

		}

		time.Sleep(1 * time.Second)
	}

}
